package com.hisense.ovcloud.warehouse.routers;

import com.hisense.ovcloud.commons.configs.base.BaseResponse;
import com.hisense.ovcloud.commons.configs.validator.BaseRouterConfiguration;
import com.hisense.ovcloud.warehouse.dto.req.GetInfoReq;
import com.hisense.ovcloud.warehouse.service.BasicDataService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import org.springdoc.core.annotations.RouterOperation;
import org.springdoc.core.annotations.RouterOperations;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.Validator;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.SynchronousSink;

import javax.annotation.PostConstruct;
import java.util.function.BiConsumer;

import static org.springframework.web.reactive.function.server.RequestPredicates.path;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;

@Configuration
public class BasicDataRoutersConfiguration extends BaseRouterConfiguration {

    private final BasicDataService basicDataService;
    private final Validator getInfoReqValidator;

    private BiConsumer<GetInfoReq, SynchronousSink<GetInfoReq>> getInfoReqValidatorHandler;

    @PostConstruct
    public void init() {
        getInfoReqValidatorHandler = (body, sink) -> validate(sink, getInfoReqValidator, body, GetInfoReq.class);
    }

    public BasicDataRoutersConfiguration(@Qualifier("getInfoReqValidator") Validator getInfoReqValidator, BasicDataService basicDataService) {
        this.getInfoReqValidator = getInfoReqValidator;
        this.basicDataService = basicDataService;
    }

    @Bean
    @RouterOperations({
            @RouterOperation(
                    path = "/basic-data/getInfoTotal",
                    method = RequestMethod.POST,
                    produces = "application/json",
                    operation = @Operation(
                            operationId = "getInfoTotal",
                            description = "getInfoTotal",
                            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
                                    description = "GetInfoReq",
                                    required = true,
                                    content = {
                                            @Content(
                                                    mediaType = "application/json",
                                                    schema = @Schema(implementation = GetInfoReq.class)
                                            )
                                    }
                            ),
                            responses = {
                                    @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
                            }
                    )
            ),
            @RouterOperation(
                    path = "/basic-data/getDeviceBySubDomain",
                    method = RequestMethod.POST,
                    produces = "application/json",
                    operation = @Operation(
                            operationId = "getDeviceBySubDomain",
                            description = "getDeviceBySubDomain",
                            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
                                    description = "getDeviceBySubDomain",
                                    required = true,
                                    content = {
                                            @Content(
                                                    mediaType = "application/json",
                                                    schema = @Schema(implementation = GetInfoReq.class)
                                            )
                                    }
                            ),
                            responses = {
                                    @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = BaseResponse.class)))
                            }
                    )
            )
    })
    public RouterFunction<ServerResponse> basicDataRoutes() {
        return RouterFunctions.nest(path("/basic-data"),
                route()
                        .POST("/getInfoTotal", req -> ServerResponse.ok().body(basicDataService.getInfoTotal(req.bodyToMono(GetInfoReq.class).handle(getInfoReqValidatorHandler)),
                                BaseResponse.class))
                        .POST("/getDeviceBySubDomain", req -> ServerResponse.ok().body(basicDataService.getDeviceBySubDomain(req.bodyToMono(GetInfoReq.class).handle(getInfoReqValidatorHandler)),
                                BaseResponse.class))
                        .build());
    }
}

